package com.ruoyi.auth.service;

import com.ruoyi.auth.domain.SmsMessage;
import com.ruoyi.auth.mq.SmsProducer;
import com.ruoyi.common.core.domain.*;
import com.ruoyi.common.core.service.IMerchantImgsService;
import com.ruoyi.common.core.service.IMerchantService;
import com.ruoyi.common.core.service.IMerchantVerificationService;
import com.ruoyi.common.core.service.IUserService;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.common.security.service.TokenService;
import com.ruoyi.system.api.model.LoginUser;
import org.apache.commons.lang.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Service
public class SmsLoginService {
    @Autowired
    private SmsProducer smsProducer;
    @Autowired
    private RedisService redisService;
    @Autowired
    private IUserService userService;
    @Autowired
    private TokenService tokenService;
    //商家
    @Autowired
    private IMerchantService merchantService;
    //商家认证
    @Autowired
    private IMerchantVerificationService merchantVerificationService;
    //商家图片
    @Autowired
    private IMerchantImgsService merchantImgsService;
    private static final String SMS_CODE_KEY = "sms:code:";
    @Value("${tencent.sms.expireMinutes}")
    private long expireMinutes;
    @Value("${tencent.sms.sendIntervalSeconds}")
    private long sendIntervalSeconds;
//    @Value("${jwt.expiration}")
//    private long jwtExpiration;

    /*
    * 商家注册、商家端登录、用户端登录统一验证码发送接口
    * type用来区分 注册或者登录所发验证码 防止注册后进入登录短时间内不能发送验证码的bug
    * */
    public R sendRegisterAndLoginCode(String phone,String type){
        // 1. 检查手机号格式
        if (!phone.matches("^1[3-9]\\d{9}$")) throw new RuntimeException("手机号格式错误");
        // 2. 判断是否重复发送（Redis防刷）
        String keyPrefix = "register".equals(type) ? "register:" : "login:";
        if (redisService.hasKey(SMS_CODE_KEY +keyPrefix+ "interval:" + phone)) {
            throw new RuntimeException("发送过于频繁，请稍后再试");
        }
        try {
            // 3. 生成6位验证码
            String code = RandomStringUtils.randomNumeric(6);
            // 4. 存入Redis并设置过期时间（验证码5分钟有效）
            redisService.setCacheObject(SMS_CODE_KEY + keyPrefix + phone, code, expireMinutes, TimeUnit.MINUTES);
            redisService.setCacheObject(SMS_CODE_KEY + keyPrefix + "interval:" + phone, "1", sendIntervalSeconds, TimeUnit.SECONDS);
            //5调用生产者接收消息
            SmsMessage smsMessage = new SmsMessage(phone, code, expireMinutes);
            smsProducer.sendMsg(smsMessage);
            return R.ok("发送成功");
        }
        catch (Exception e) {
            // 8. 异常时清除防刷 Key
            redisService.deleteObject(SMS_CODE_KEY +keyPrefix+ "interval:" + phone);
            throw new RuntimeException("发送失败，请重试");
        }
    }
    /*
    * 商家端登录、用户端登录接口
    * */
    public R login(String phone, String code){

        // 1. 验证码校验
        String redisCode = redisService.getCacheObject(SMS_CODE_KEY+"login:" + phone);
        if (!code.equals(redisCode)) throw new RuntimeException("验证码错误");
        // 2. 删除Redis中的验证码
        redisService.deleteObject(SMS_CODE_KEY+"login:" + phone);
        //如果用户首次登录向用户表添加数据
        User user = userService.selectUserByPhone(phone);
        if (user == null) {
            user = new User();
            user.setPhone(phone);
            user.setUserName("用户"+phone);
            user.setNickName("用户昵称"+phone);
            user.setPassword("123456");

           userService.insertUser(user);
        }
        //生成符合若依自带的token方便进行认证
        //导入tokenService 生成创造token所需的loginUser
        LoginUser loginUser = new LoginUser();
        loginUser.setUserid((Long.parseLong(user.getId())));// 你的 User.id（String转Long）
        loginUser.setUsername(user.getUserName()); // 你的 User.userName
        loginUser.setIpaddr("127.0.0.1");
        Map<String, Object> message = tokenService.createToken(loginUser);
        //用户端返回token 和 userId
        Object o = message.get("access_token");
        String token = o.toString();
        String userId = user.getId();
        Map<String, Object> rspMap = new HashMap<String, Object>();
        rspMap.put("token", token);
        rspMap.put("userinfo", user);
        return R.ok(rspMap, "登录成功");
    }
    /*
    * 商家端注册接口
    * */
    public R register(Map<String, Object> params){
        System.out.println(params);
        String username = (String) params.get("username");
        String phoneNumber = (String) params.get("phoneNumber");
        String idCard = (String) params.get("idCard");
        String code = (String) params.get("code");
        String name = (String) params.get("name");
        String businessLicenseId = (String) params.get("businessLicenseId");
        String operatingArea = (String) params.get("operatingArea");
        String address = (String) params.get("address");
        String description = (String) params.get("description");
        String front = (String) params.get("front");
        String opposite = (String) params.get("opposite");
        String businessLicenseImg = (String) params.get("businessLicenseImg");
        String img = (String) params.get("img");
        // 1. 验证码校验
        String redisCode = redisService.getCacheObject(SMS_CODE_KEY +"register:"+ phoneNumber);
        System.out.println("phoneNumber:"+phoneNumber);
        System.out.println("code:"+code);
        System.out.println("redisCode:"+redisCode);
        if (!code.equals(redisCode))
        {
            throw new RuntimeException("验证码错误");
        }else {
            // 2. 删除Redis中的验证码
            redisService.deleteObject(SMS_CODE_KEY +"register:"+ phoneNumber);
            User user = new User();
            user.setUserName(username);
            user.setPhone(phoneNumber);
            user.setPassword("123456");
            userService.insertUser(user);
            Merchant merchant = new Merchant();
            merchant.setUserId(Integer.parseInt(user.getId()));
            merchant.setName(name);
            merchant.setOperatingArea(operatingArea);
            merchant.setAddress(address);
            merchant.setDescription(description);
            merchant.setAuditStatusId(0L);
            Long mid = (long) merchantService.insertMerchant(merchant);
            MerchantVerification merchantVerification = new MerchantVerification();
            merchantVerification.setMid(mid);
            merchantVerification.setIdCard(idCard);
            merchantVerification.setMobile(phoneNumber);
            merchantVerification.setBusinessLicenseId(businessLicenseId);
            merchantVerification.setFront( front);
            merchantVerification.setOpposite(opposite);
            merchantVerification.setBusinessLicenseImg(businessLicenseImg);
            merchantVerificationService.insertMerchantVerification(merchantVerification);
            MerchantImgs merchantImgs = new MerchantImgs();
            merchantImgs.setMid(mid);
            merchantImgs.setImg(img);
            merchantImgsService.insertMerchantImgs(merchantImgs);
        }
        return R.ok("注册成功");
    }
}
